package com.zhiche.wms.service.inbound.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.zhiche.wms.configuration.MyConfigurationProperties;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.InterfaceAddrEnum;
import com.zhiche.wms.core.supports.enums.InterfaceEventEnum;
import com.zhiche.wms.core.supports.enums.SysSourceEnum;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.core.utils.HttpRequestUtil;
import com.zhiche.wms.core.utils.SnowFlakeId;
import com.zhiche.wms.domain.mapper.inbound.InboundPutawayHeaderMapper;
import com.zhiche.wms.domain.mapper.otm.OtmOrderReleaseMapper;
import com.zhiche.wms.domain.model.base.StoreLocation;
import com.zhiche.wms.domain.model.base.Storehouse;
import com.zhiche.wms.domain.model.inbound.*;
import com.zhiche.wms.domain.model.log.ItfExplogHeader;
import com.zhiche.wms.domain.model.log.ItfExplogLine;
import com.zhiche.wms.domain.model.movement.MovementHeader;
import com.zhiche.wms.domain.model.movement.MovementLine;
import com.zhiche.wms.domain.model.opbaas.ExceptionRegister;
import com.zhiche.wms.domain.model.opbaas.OpTask;
import com.zhiche.wms.domain.model.opbaas.StatusLog;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.service.base.IBusinessDocNumberService;
import com.zhiche.wms.service.base.IStoreLocationService;
import com.zhiche.wms.service.base.IStorehouseService;
import com.zhiche.wms.service.common.IntegrationService;
import com.zhiche.wms.service.constant.MovementType;
import com.zhiche.wms.service.constant.SourceSystem;
import com.zhiche.wms.service.constant.Status;
import com.zhiche.wms.service.dto.OTMEvent;
import com.zhiche.wms.service.inbound.*;
import com.zhiche.wms.service.log.IItfExplogHeaderService;
import com.zhiche.wms.service.movement.IMovementHeaderService;
import com.zhiche.wms.service.opbaas.IExceptionRegisterService;
import com.zhiche.wms.service.opbaas.IStatusLogService;
import com.zhiche.wms.service.opbaas.ITaskService;
import com.zhiche.wms.service.otm.IOtmOrderReleaseService;
import com.zhiche.wms.service.sys.IUserService;
import com.zhiche.wms.service.utils.BusinessNodeExport;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 入库单头 服务实现类
 * </p>
 *
 * @author qichao
 * @since 2018-06-08
 */
@Service
public class InboundPutawayHeaderServiceImpl extends ServiceImpl<InboundPutawayHeaderMapper, InboundPutawayHeader> implements IInboundPutawayHeaderService {

    @Autowired
    private IInboundNoticeHeaderService inboundNoticeHeaderService;
    @Autowired
    private IInboundNoticeLineService inboundNoticeLineService;
    @Autowired
    private IStoreLocationService storeLocationService;
    @Autowired
    private IBusinessDocNumberService businessDocNumberService;
    @Autowired
    private IMovementHeaderService movementHeaderService;
    @Autowired
    private IInboundPutawayLineService inboundPutawayLineService;
    @Autowired
    private SnowFlakeId snowFlakeId;
    @Autowired
    private IUserService userService;
    @Autowired
    private IntegrationService integrationService;
    @Autowired
    private IOtmOrderReleaseService releaseService;
    @Autowired
    private BusinessNodeExport nodeExport;
    @Autowired
    private ITaskService taskService;
    @Autowired
    private IInboundInspectLineService inspectLineService;
    @Autowired
    private IInboundInspectHeaderService inspectHeaderService;
    @Autowired
    private IStatusLogService statusLogService;
    @Autowired
    private OtmOrderReleaseMapper otmOrderReleaseMapper;
    @Autowired
    private MyConfigurationProperties properties;
    @Autowired
    private IExceptionRegisterService registerService;
    @Autowired
    private IItfExplogHeaderService explogHeaderService;
    @Autowired
    private IStorehouseService storehouseService;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized InboundPutawayHeader updateByNoticeLineId(Long noticeLineId, String inboundType, String genMethod) {

        //获取入库通知单明细
        InboundNoticeLine inboundNoticeLine = inboundNoticeLineService.selectById(noticeLineId);
        if (Objects.isNull(inboundNoticeLine)) {
            throw new BaseException("入库通知单明细不存在！");
        }
        if (inboundNoticeLine.getStatus().equals(Status.Inbound.ALL)) {
            throw new BaseException("已入库不能重复入库！");
        }
        if (inboundNoticeLine.getStatus().equals(Status.Inbound.CANCEL)) {
            throw new BaseException("入库已取消，不能入库！");
        }
        //if(inboundNoticeLine.getStatus().equals(Status.inbound.ALL)) throw new BaseException("入库通知单明细不存在！");
        //获取入库通知单头
        InboundNoticeHeader inboundNoticeHeader =
                inboundNoticeHeaderService.selectById(inboundNoticeLine.getHeaderId());
        //得到可用储位
        StoreLocation storeLocation = storeLocationService.getUsableLocation(inboundNoticeHeader.getStoreHouseId());
        if (Objects.isNull(storeLocation)) {
            throw new BaseException("无可用库位！");
        }
        User loginUser = null;
        if (SourceSystem.AUTO.equals(genMethod)) {
            loginUser = new User();
            loginUser.setName(SysSourceEnum.AUTO.getName());
            loginUser.setCode(SysSourceEnum.AUTO.getCode());
        } else if (SourceSystem.HONEYWELL.equals(genMethod)) {
            loginUser = new User();
            loginUser.setName(SysSourceEnum.HONEYWELL.getName());
            loginUser.setCode(SysSourceEnum.HONEYWELL.getCode());
        } else {
            loginUser = userService.getLoginUser();
        }

        //入库单头
        InboundPutawayHeader inboundPutawayHeader = new InboundPutawayHeader();
        BeanUtils.copyProperties(inboundNoticeHeader, inboundPutawayHeader);
        inboundPutawayHeader.setNoticeId(inboundNoticeHeader.getId());
        inboundPutawayHeader.setInboundNo(businessDocNumberService.getInboundPutAwayNo());
        inboundPutawayHeader.setId(snowFlakeId.nextId());
        inboundPutawayHeader.setType(inboundType);
        inboundPutawayHeader.setGenMethod(genMethod);
        inboundPutawayHeader.setStatus(Status.AUDIT);
        inboundPutawayHeader.setUserModified(loginUser.getName());
        inboundPutawayHeader.setUserCreate(loginUser.getName());
        inboundPutawayHeader.setInboundTime(new Date());
        inboundPutawayHeader.setGmtCreate(null); //创建时间、修改时间使用数据库自动处理
        inboundPutawayHeader.setGmtModified(null);

        //入库单明细
        InboundPutawayLine inboundPutawayLine = new InboundPutawayLine();
        BeanUtils.copyProperties(inboundNoticeLine, inboundPutawayLine);
        inboundPutawayLine.setHeaderId(inboundPutawayHeader.getId());
        inboundPutawayLine.setNoticeLineId(inboundNoticeLine.getId());
        inboundPutawayLine.setLocationId(storeLocation.getId());
        String areaName = storeLocation.getStoreAreaName();
        String locDetail = "";
        if (StringUtils.isNotBlank(areaName) && areaName.endsWith("区")) {
            locDetail = areaName.concat(storeLocation.getName());
        } else if (StringUtils.isNotBlank(areaName) && !areaName.endsWith("区")) {
            locDetail = areaName.concat("区").concat(storeLocation.getName());
        } else if (StringUtils.isBlank(areaName)) {
            locDetail = storeLocation.getName();
        }
        inboundPutawayLine.setLocationNo(locDetail);
        inboundPutawayLine.setInboundQty(inboundNoticeLine.getExpectQty());
        inboundPutawayLine.setInboundNetWeight(inboundNoticeLine.getExpectNetWeight());
        inboundPutawayLine.setInboundGrossWeight(inboundNoticeLine.getExpectGrossWeight());
        inboundPutawayLine.setInboundGrossCubage(inboundNoticeLine.getExpectGrossCubage());
        inboundPutawayLine.setInboundPackedCount(inboundNoticeLine.getExpectPackedCount());
        inboundPutawayLine.setId(snowFlakeId.nextId());
        inboundPutawayLine.setGmtCreate(null);//创建时间、修改时间使用数据库自动处理
        inboundPutawayLine.setGmtModified(null);
        inboundPutawayHeader.addInboundPutawayLine(inboundPutawayLine);

        boolean result = insertMovementByPutaway(inboundPutawayHeader, loginUser) && savePutAway(inboundPutawayHeader);
        if (!result) {
            throw new BaseException("入库失败");
        }
        inboundNoticeHeaderService.updateStatus(inboundNoticeHeader.getId());

        // 确认入库后，自动完成前段的寻车、移车、提车任务以及收车质检任务(如果存在质检单)
        updateTaskFinish(inboundNoticeLine, loginUser);

        //2019-1-28 fix 增加重庆前置库1库,入库信息回传ERP(ERP入库信息-->工厂)

        Storehouse storehouse = storehouseService.selectById(inboundNoticeHeader.getStoreHouseId());

        // 仓库根据code 判断是否发送ERP,如后续调整基础数据时调整......
        if (storehouse != null && "重庆前置库1库".equals(storehouse.getCode())) {
            inboundERP(inboundNoticeLine,
                    inboundNoticeHeader,
                    loginUser,
                    inboundPutawayHeader,
                    inboundPutawayLine);
        }

        //如果是otm下发入库信息.入库成功,推送信息到OTM
        updateSendOTM(noticeLineId, inboundNoticeLine, loginUser);

        return inboundPutawayHeader;
    }

    //重庆前置库1库 传送ERP
    private void inboundERP(InboundNoticeLine inboundNoticeLine,
                            InboundNoticeHeader inboundNoticeHeader,
                            User loginUser,
                            InboundPutawayHeader inboundPutawayHeader,
                            InboundPutawayLine inboundPutawayLine) {
        String url = properties.getFetchInboundFromTMSUrl() + InterfaceAddrEnum.INBOUND_ERP.getAddress();
        Integer timeOut = properties.getSocketTimeOut();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String encode_key = "ZL12345";                      //简单的ERP接口鉴权(头携带key)
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("encode-key", encode_key);
        //vin           车架号
        //custshipno    客户运单号(ILS指令客户订单号和客户运单号一致)
        //dt_inware     入库时间,yyyy-MM-dd hh24:mi:ss
        //userno        入库人
        //warehouse     入库仓库：重庆前置库
        //pos           库位
        //type          入库类型，1.正常入库 ；2.异常入库
        map.put("vin", inboundNoticeLine.getLotNo1());
        map.put("custshipno", inboundNoticeLine.getOwnerOrderNo());
        map.put("dt_inware", sdf.format(inboundPutawayHeader.getInboundTime()));
        map.put("userno", loginUser.getName());
        map.put("warehouse", "重庆前置库");
        map.put("pos", inboundPutawayLine.getLocationNo());
        EntityWrapper<ExceptionRegister> erEW = new EntityWrapper<>();
        erEW.eq("vin", inboundNoticeLine.getLotNo1())
                .ne("status", TableStatusEnum.STATUS_0.getCode())
                .ne("task_node", TableStatusEnum.STATUS_50.getCode());//非出库节点
        int count = registerService.selectCount(erEW);
        if (count > 0) {
            map.put("type", TableStatusEnum.STATUS_2.getCode());
        } else {
            map.put("type", TableStatusEnum.STATUS_1.getCode());
        }
        String erpParam = JSONObject.toJSONString(map);
        //日志记录
        ItfExplogHeader exH = getItfExplogHeader(inboundNoticeHeader);

        ItfExplogLine exl = getItfExplogLine(inboundNoticeLine, url, erpParam, exH);
        if (logger.isInfoEnabled()) {
            logger.info("入库确认连接ERP url:{},param:{}", url, erpParam);
        }
        String erpRes;
        try {
            erpRes = HttpRequestUtil.sendHttpPost(url, headerMap, map, timeOut);
            if (logger.isInfoEnabled()) {
                logger.info("入库确认连接ERP url:{},result:{}", url, erpRes);
            }
        } catch (Exception e) {
            insertLog(exH, exl, TableStatusEnum.STATUS_N);
            logger.error("入库确认连接ERP url:{},param:{}  超时异常:{}", url, erpParam, e);
            throw new BaseException("入库连接ERP异常");
        }
        if (StringUtils.isNotBlank(erpRes)) {
            JSONObject jsonObject = JSONObject.parseObject(erpRes);
            Boolean success = jsonObject.getBoolean("success");
            if (!success) {
                String message = jsonObject.getString("message");
                insertLog(exH, exl, TableStatusEnum.STATUS_N);
                throw new BaseException("入库同步ERP失败," + message);
            } else {
                insertLog(exH, exl, TableStatusEnum.STATUS_Y);
            }
        } else {
            insertLog(exH, exl, TableStatusEnum.STATUS_N);
            throw new BaseException("入库同步ERP失败,响应结果为空");
        }
    }

    private ItfExplogLine getItfExplogLine(InboundNoticeLine inboundNoticeLine, String url, String erpParam, ItfExplogHeader exH) {
        ItfExplogLine exl = new ItfExplogLine();
        exl.setId(snowFlakeId.nextId());
        exl.setHeaderId(exH.getId());
        exl.setExportType("CQ入库确认传ERP");
        exl.setRelationId(inboundNoticeLine.getId());
        exl.setTargetSource("ERP-TMS-IN");
        exl.setInterfaceUrl(url);
        exl.setExportStartTime(new Date());
        exl.setExportRemarks("CQ入库确认传ERP");
        exl.setDataContent(erpParam);
        ArrayList<ItfExplogLine> lines = Lists.newArrayList();
        lines.add(exl);
        exH.setItfExplogLines(lines);
        return exl;
    }

    private ItfExplogHeader getItfExplogHeader(InboundNoticeHeader inboundNoticeHeader) {
        ItfExplogHeader exH = new ItfExplogHeader();
        exH.setId(snowFlakeId.nextId());
        exH.setExportType("CQ入库确认传ERP");
        exH.setRelationId(inboundNoticeHeader.getId());
        exH.setTargetSource("ERP-TMS-IN");
        exH.setExportRemarks("CQ入库确认传ERP");
        return exH;
    }

    private void insertLog(ItfExplogHeader exH, ItfExplogLine exl, TableStatusEnum status1) {
        exl.setExportStatus(status1.getCode());
        exH.setExportStatus(status1.getCode());
        //记录wms日志
        new Thread(() -> {
            explogHeaderService.insertWithLines(exH);
        }).start();
    }

    private void updateSendOTM(Long noticeLineId, InboundNoticeLine inboundNoticeLine, User loginUser) {

        String key = inboundNoticeLine.getLineSourceKey();
        if (StringUtils.isNotBlank(key)) {
            EntityWrapper<OtmOrderRelease> ew = new EntityWrapper<>();
            ew.eq("release_gid", key)
                    .ne("status", TableStatusEnum.STATUS_50.getCode());
            List<OtmOrderRelease> otmOrderReleases = releaseService.selectList(ew);
            if (CollectionUtils.isNotEmpty(otmOrderReleases)) {
                if (otmOrderReleases.size() > 1) {
                    throw new BaseException("通知明细:" + noticeLineId + "存在多条ReleaseGid:" + key);
                }
                OtmOrderRelease release = otmOrderReleases.get(0);
                //调整release 状态为已入库
                setReleaseAndStatusLog(loginUser, release);

                OTMEvent event = integrationService.getOtmEvent(String.valueOf(noticeLineId),
                        key,
                        InterfaceEventEnum.BS_WMS_IN.getCode(),
                        release.getShipmentGid(),
                        "入库回传OTM");
                String res = nodeExport.exportEventToOTM(event);
                try {
                    integrationService.insertExportLog(
                            String.valueOf(noticeLineId),
                            event, res, "入库回传OTM",
                            InterfaceEventEnum.BS_WMS_IN.getCode());
                } catch (Exception e) {
                    logger.error("入库推送OTM失败:{}", e);
                    throw new BaseException("入库推送OTM失败");
                }
            }
        }

    }

    private void setReleaseAndStatusLog(User loginUser, OtmOrderRelease release) {
        OtmOrderRelease oor = new OtmOrderRelease();
        oor.setStatus(TableStatusEnum.STATUS_BS_INBOUND.getCode());
        oor.setId(release.getId());
        releaseService.updateById(oor);
        StatusLog statusLog = new StatusLog();
        statusLog.setTableType(TableStatusEnum.STATUS_10.getCode());
        statusLog.setTableId(String.valueOf(release.getId()));
        statusLog.setStatus(TableStatusEnum.STATUS_BS_INBOUND.getCode());
        statusLog.setStatusName(TableStatusEnum.STATUS_BS_INBOUND.getDetail());
        statusLog.setUserCreate(loginUser.getName());
        statusLogService.insert(statusLog);
    }

    private void updateTaskFinish(InboundNoticeLine inboundNoticeLine, User loginUser) {
        EntityWrapper<OpTask> taskEW = new EntityWrapper<>();
        taskEW.eq("waybill_no", inboundNoticeLine.getLineSourceKey())
                .in("status", new String[]{TableStatusEnum.STATUS_10.getCode(),
                        TableStatusEnum.STATUS_20.getCode()});
        OpTask task = new OpTask();
      /*  task.setDriverCode(loginUser.getCode());
        task.setDriverPhone(loginUser.getMobile());
        task.setDriverName(loginUser.getName());*/
        task.setStatus(TableStatusEnum.STATUS_30.getCode());
        task.setStartTime(new Date());
        task.setFinishTime(new Date());
        task.setUserModified(loginUser.getName());
        taskService.update(task, taskEW);
        //质检
        EntityWrapper<InboundInspectLine> inspectLineEW = new EntityWrapper<>();
        inspectLineEW.eq("notice_line_id", inboundNoticeLine.getId())
                .eq("status", TableStatusEnum.STATUS_0.getCode());
        InboundInspectLine line = new InboundInspectLine();
        line.setStatus(TableStatusEnum.STATUS_10.getCode());
        line.setRemarks("入库质检合格");
        line.setDealMethod(TableStatusEnum.STATUS_10.getCode());
        inspectLineService.update(line, inspectLineEW);

        EntityWrapper<InboundInspectHeader> headEW = new EntityWrapper<>();
        headEW.eq("notice_id", inboundNoticeLine.getHeaderId())
                .eq("status", TableStatusEnum.STATUS_0.getCode());
        InboundInspectHeader inspectHeader = new InboundInspectHeader();
        inspectHeader.setStatus(TableStatusEnum.STATUS_10.getCode());
        inspectHeader.setOrderDate(new Date());
        inspectHeader.setInspector(loginUser.getName());
        inspectHeader.setQualifiedSumQty(BigDecimal.ONE);
        inspectHeader.setIsFinish(1);
        inspectHeaderService.update(inspectHeader, headEW);
    }


    @Override
    public boolean savePutAway(InboundPutawayHeader inboundPutawayHeader) {
        return insert(inboundPutawayHeader) &&
                inboundPutawayLineService.insertBatch(inboundPutawayHeader.getInboundPutawayLineList());
    }

    /**
     * 根据入库单插入移位单
     */
    @Override
    public boolean insertMovementByPutaway(InboundPutawayHeader inboundPutawayHeader, User loginUser) {
        //移位单头
        MovementHeader movementHeader = new MovementHeader();
        movementHeader.setMovementNo(businessDocNumberService.getMovementNo());
        movementHeader.setOwnerId(inboundPutawayHeader.getOwnerId());
        movementHeader.setStoreHouseId(inboundPutawayHeader.getStoreHouseId());
        movementHeader.setOrderDate(inboundPutawayHeader.getInboundTime());
        movementHeader.setBusinessType(MovementType.INBOUND_MOVE);
        movementHeader.setBusinessDocId(inboundPutawayHeader.getId());
        movementHeader.setUserModified(loginUser.getName());
        movementHeader.setUserCreate(loginUser.getName());
        for (InboundPutawayLine inboundPutawayLine : inboundPutawayHeader.getInboundPutawayLineList()) {
            MovementLine movementLine = new MovementLine();
            BeanUtils.copyProperties(inboundPutawayLine, movementLine);
            movementLine.setHeaderId(movementHeader.getId());
            movementLine.setRelationLineId(inboundPutawayLine.getId());
            movementLine.setType(MovementType.LINE_INTO);
            movementLine.setDestinationLocationId(inboundPutawayLine.getLocationId());
            movementLine.setQty(inboundPutawayLine.getInboundQty());
            movementLine.setNetWeight(inboundPutawayLine.getInboundNetWeight());
            movementLine.setGrossWeight(inboundPutawayLine.getInboundGrossWeight());
            movementLine.setGrossCubage(inboundPutawayLine.getInboundGrossCubage());
            movementLine.setPackedCount(inboundPutawayLine.getInboundPackedCount());
            movementHeader.addMovementLine(movementLine);
        }
        //保存并审核移位单、入库单
        return movementHeaderService.createAndAuditMovenment(movementHeader);
    }


    @Transactional(rollbackFor = Exception.class)
    public InboundPutawayHeader updateNoticeLineWithLocationId(Long noticeLineId,
                                                               String inboundType,
                                                               String genMethod,
                                                               Long storeLoactionId) {

        if (Objects.isNull(storeLoactionId)) throw new BaseException("未获取到选中库位");
        //获取入库通知单明细
        InboundNoticeLine inboundNoticeLine = inboundNoticeLineService.selectById(noticeLineId);
        if (Objects.isNull(inboundNoticeLine)) throw new BaseException("入库通知单明细不存在！");
        if (inboundNoticeLine.getStatus().equals(Status.Inbound.ALL)) throw new BaseException("已入库不能重复入库！");
        if (inboundNoticeLine.getStatus().equals(Status.Inbound.CANCEL)) throw new BaseException("入库已取消，不能入库！");
        User loginUser = null;
        if (SourceSystem.AUTO.equals(genMethod)) {
            loginUser = new User();
            loginUser.setCode(SysSourceEnum.AUTO.getCode());
            loginUser.setName(SysSourceEnum.AUTO.getName());
        } else if (SourceSystem.HONEYWELL.equals(genMethod)) {
            loginUser = new User();
            loginUser.setCode(SysSourceEnum.HONEYWELL.getCode());
            loginUser.setName(SysSourceEnum.HONEYWELL.getName());
        } else {
            loginUser = userService.getLoginUser();
        }
//        if(inboundNoticeLine.getStatus().equals(Status.inbound.ALL)) throw new BaseException("入库通知单明细不存在！");
        //获取入库通知单头
        InboundNoticeHeader inboundNoticeHeader =
                inboundNoticeHeaderService.selectById(inboundNoticeLine.getHeaderId());

        //得到可用储位
        List<StoreLocation> storeLocations = storeLocationService.
                listUsableLocation(inboundNoticeHeader.getStoreHouseId());
        if (CollectionUtils.isEmpty(storeLocations)) throw new BaseException("无可用仓储库位！");
        StoreLocation storeLocation = null;
        for (StoreLocation storeLocationItem : storeLocations) {
            if (storeLocationItem.getId().equals(storeLoactionId)) storeLocation = storeLocationItem;
        }
        if (Objects.isNull(storeLocation)) throw new BaseException("该库位不可用！");

        //入库单头
        InboundPutawayHeader inboundPutawayHeader = new InboundPutawayHeader();
        BeanUtils.copyProperties(inboundNoticeHeader, inboundPutawayHeader);
        inboundPutawayHeader.setNoticeId(inboundNoticeHeader.getId());
        inboundPutawayHeader.setInboundNo(businessDocNumberService.getInboundPutAwayNo());
        inboundPutawayHeader.setId(snowFlakeId.nextId());
        inboundPutawayHeader.setType(inboundType);
        inboundPutawayHeader.setGenMethod(genMethod);
        inboundPutawayHeader.setStatus(Status.AUDIT);
        inboundPutawayHeader.setInboundTime(new Date());
        inboundPutawayHeader.setUserCreate(loginUser.getName());
        inboundNoticeHeader.setUserModified(loginUser.getName());
        inboundPutawayHeader.setGmtCreate(null); //创建时间、修改时间使用数据库自动处理
        inboundPutawayHeader.setGmtModified(null);

        //入库单明细
        InboundPutawayLine inboundPutawayLine = new InboundPutawayLine();
        BeanUtils.copyProperties(inboundNoticeLine, inboundPutawayLine);
        inboundPutawayLine.setHeaderId(inboundPutawayHeader.getId());
        inboundPutawayLine.setNoticeLineId(inboundNoticeLine.getId());
        inboundPutawayLine.setLocationId(storeLocation.getId());
        String areaName = storeLocation.getStoreAreaName();
        String locDetail = "";
        if (StringUtils.isNotBlank(areaName) && areaName.endsWith("区")) {
            locDetail = areaName.concat(storeLocation.getName());
        } else if (StringUtils.isNotBlank(areaName) && !areaName.endsWith("区")) {
            locDetail = areaName.concat("区").concat(storeLocation.getName());
        } else if (StringUtils.isBlank(areaName)) {
            locDetail = storeLocation.getName();
        }
        inboundPutawayLine.setLocationNo(locDetail);
        inboundPutawayLine.setInboundQty(inboundNoticeLine.getExpectQty());
        inboundPutawayLine.setInboundNetWeight(inboundNoticeLine.getExpectNetWeight());
        inboundPutawayLine.setInboundGrossWeight(inboundNoticeLine.getExpectGrossWeight());
        inboundPutawayLine.setInboundGrossCubage(inboundNoticeLine.getExpectGrossCubage());
        inboundPutawayLine.setInboundPackedCount(inboundNoticeLine.getExpectPackedCount());
        inboundPutawayLine.setId(snowFlakeId.nextId());
        inboundPutawayLine.setGmtCreate(null);//创建时间、修改时间使用数据库自动处理
        inboundPutawayLine.setGmtModified(null);
        inboundPutawayHeader.addInboundPutawayLine(inboundPutawayLine);

        boolean result = insertMovementByPutaway(inboundPutawayHeader, loginUser) && savePutAway(inboundPutawayHeader);
        if (!result) {
            throw new BaseException("入库失败");
        }
        inboundNoticeHeaderService.updateStatus(inboundNoticeHeader.getId());

        // 确认入库后，自动完成前段的寻车、移车、提车任务以及收车质检任务(如果存在质检单)
        updateTaskFinish(inboundNoticeLine, loginUser);

        //2019-1-28 fix 增加重庆前置库1库,入库信息回传ERP(ERP入库信息-->工厂)
        Storehouse storehouse = storehouseService.selectById(inboundNoticeHeader.getStoreHouseId());

        // 仓库根据code 判断是否发送ERP,如后续调整基础数据时调整......
        if (storehouse != null && "重庆前置库1库".equals(storehouse.getCode())) {
            inboundERP(inboundNoticeLine,
                    inboundNoticeHeader,
                    loginUser,
                    inboundPutawayHeader,
                    inboundPutawayLine);
        }

        //如果是otm下发入库信息.入库成功,推送信息到OTM
        updateSendOTM(noticeLineId, inboundNoticeLine, loginUser);

        return inboundPutawayHeader;
    }

    /**
     * 提示目标库位
     *
     * @param headerId
     * @param vin
     * @return
     */
    public String getRealDestAddress(Long headerId, String vin) {
        InboundNoticeHeader inboundNoticeHeader = inboundNoticeHeaderService.selectById(headerId);
        if (null != inboundNoticeHeader) {
            if (null != inboundNoticeHeader) {
                OtmOrderRelease param = new OtmOrderRelease();
                param.setShipmentGid(inboundNoticeHeader.getSourceKey());
                param.setVin(vin);
                OtmOrderRelease otmOrderRelease = otmOrderReleaseMapper.selectOne(param);
                if (Objects.nonNull(otmOrderRelease)) {
                    if (StringUtils.isNotEmpty(otmOrderRelease.getDestLocationGid())) {
                        return ",请确认入库地址是否是：" + otmOrderRelease.getDestLocationGid() + "【" + otmOrderRelease.getDestLocationName() + "】";
                    }
                }
            }
        }
        return "";
    }
}
